/*
 * LDIR
 *
 * LDIR, a GPS cartography application built for Let's Do It Romania eco
 * campaign.
 * Copyright (C) 2010 Genera Software <office@generasoftware.com>
 *
 * http://generasoftware.com/
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
// This file defines the API for Json.dll
#ifndef __JSON_H__
#define __JSON_H__

//  Include Files

#include <e32base.h>	// CBase
#include <e32std.h>	 // TBuf
#include <stringpool.h>

#include "Entity.h"

class MJsonContentHandler
{
public:
    virtual void OnNullL() = 0;
    virtual void OnBooleanL(TBool aBool) = 0;
    virtual void OnIntegerL(TInt aInt) = 0;
    virtual void OnRealL(TReal aReal) = 0;
    virtual void OnNumberL(const TDesC8& aNumber) = 0;
    virtual void OnDesL(const TDesC8& aDesc) = 0;
    virtual void OnStartMapL() = 0;
    virtual void OnMapKeyL(const TDesC8& aKey) = 0;
    virtual void OnEndMapL() = 0;
    virtual void OnStartArrayL() = 0;
    virtual void OnEndArrayL() = 0;
    virtual void OnErrorL(TInt aErrCode, const TDesC8& aErrDesc) = 0;
};

//  Class Definitions

class CJsonParserImpl;
class CJsonGeneratorImpl;

class CJsonParser : public CBase, MJsonContentHandler
    {
public:
    enum TParserStatus
    {
        /** no error was encountered */
        EStatusOk,
        /** a client callback returned zero, stopping the parse */
        EStatusClientCanceled,
        /** The parse cannot yet complete because more json input text
        *  is required, call yajl_parse with the next buffer of input text.
        *  (pertinent only when stream parsing) */
        EStatusInsufficientData,
        /** An error occurred during the parse.  Call yajl_get_error for
        *  more information about the encountered error */
        EStatusError
    };
    // Creation & destruction.
    IMPORT_C static CJsonParser* NewL(const TStringTable& aDictionary, TBool aAllowComments = EFalse, TBool aCheckUTF8 = ETrue);
    IMPORT_C static CJsonParser* NewLC(const TStringTable& aDictionary, TBool aAllowComments = EFalse, TBool aCheckUTF8 = ETrue);
    IMPORT_C ~CJsonParser();
public: // new functions
    IMPORT_C TVersion Version() const;
    IMPORT_C void PrepareParser();
    IMPORT_C TInt ParseL(const TDesC8& aData);
    // Might leave because we allocate the parser here
    IMPORT_C void SetContentHandlerL(MJsonContentHandler* aContenthandler);
    IMPORT_C void ResetData();
    // Symbian Callbacks
    IMPORT_C virtual void OnNullL();
    IMPORT_C virtual void OnBooleanL(TBool aBool);
    IMPORT_C virtual void OnIntegerL(TInt aInt);
    IMPORT_C virtual void OnRealL(TReal aReal);
    IMPORT_C virtual void OnNumberL(const TDesC8& aNumber);
    IMPORT_C virtual void OnDesL(const TDesC8& aDesc);
    IMPORT_C virtual void OnStartMapL();
    IMPORT_C virtual void OnMapKeyL(const TDesC8& aKey);
    IMPORT_C virtual void OnEndMapL();
    IMPORT_C virtual void OnStartArrayL();
    IMPORT_C virtual void OnEndArrayL();
    IMPORT_C virtual void OnErrorL(TInt aErrCode, const TDesC8& aErrDesc);

    IMPORT_C CEntity* DOM();
    IMPORT_C CEntity* GetDOM(); // loses ownership

private:  // 2nd phase
    CJsonParser(const TStringTable& aDictionary);
    void ConstructL(TBool aAllowComments, TBool aCheckUTF8);
private: // data
    CJsonParserImpl* iParserImpl;
    CEntity* iCurrentNode;
    CEntity* iDom;
    const TStringTable& iDictionaryTable;
    RStringPool iDictionary;
    };


class CJsonGenerator : public CBase
{
public:
    /** generator status codes */
    enum TGeneratorStatus{
        /** no error */
        EGenStatusOk = 0,
        /** at a point where a map key is generated, a function other than
        *  yajl_gen_string was called */
        EGenKeysMustBeStrings,
        /** YAJL's maximum generation depth was exceeded.  see
        *  YAJL_MAX_DEPTH */
        EGenMaxDepthExceeded,
        /** A generator function (yajl_gen_XXX) was called while in an error
        *  state */
        EGenInErrorState,
        /** A complete JSON document has been generated */
        EGenComplete
    } yajl_gen_status;

    IMPORT_C static CJsonGenerator* NewL(const TStringTable& aDictionary, TBool aBeautify = ETrue);
    IMPORT_C static CJsonGenerator* NewLC(const TStringTable& aDictionary, TBool aBeautify = ETrue);
    IMPORT_C ~CJsonGenerator();
    IMPORT_C void SetRoot(CEntity* aRoot, TBool aOwnsEntity = EFalse);
    IMPORT_C void AddChildL(CEntity* aNode);
    IMPORT_C TInt GenerateL(HBufC8*& aBuffer);
    IMPORT_C TInt GenerateL(RWriteStream& aStream);
    IMPORT_C TVersion Version() const;
private:
    CJsonGenerator();
    void ConstructL(const TStringTable& aDictionary, TBool aBeautify);
private: // data
    CJsonGeneratorImpl* iGenerator;
    CEntity* iRoot;
    TBool iOwnsEntity;
};


#endif  // __JSON_H__

